<template>
    <el-upload
      class="avatar-uploader"
      accept=".png,.jpg,.jpeg"
      :show-file-list="false"
      :http-request="onHttpRequest"
    >
      <div v-if="modelValue" class="avatar">
        <img :src="modelValue" alt="" />
        <div class="handle">
          <el-icon class="icon-delete" @click.stop="handleDelete">
            <Delete />
          </el-icon>
        </div>
      </div>
  
      <el-icon v-else class="avatar-uploader-icon">
        <Plus />
      </el-icon>
    </el-upload>
  </template>
  
  <script>
  import request from "@/utils/request";
  import { ElMessage } from "element-plus";
  
  export default {
    name: "avatar-uploader",
  
    props: {
      modelValue: {
        type: String,
        required: true,
      },
  
      // 文件大小限制，2M
      //  M => KB => b
      limit: {
        type: Number,
        default() {
          return 2 * 1024 * 1024;
        },
      },
  
      // 文件类型限制
      accept: {
        type: Array,
        default() {
          return ["image/jpeg", "image/jpg", "image/png"];
        },
      },
    },
  
    emits: ["update:modelValue"],
  
    methods: {
      /**
       * 覆盖默认的xhr行为
       * @param {Object} options 请求相关的配置项
       */
      onHttpRequest(options) {
        console.log(options);
  
        const { size, type } = options.file;
        if (!this.fileCheck(size, type)) {
          ElMessage.error("文件类型或大小不符合要求");
          return;
        }
  
        request
          .post(
            "/app/base/comm/upload",
            {
              file: options.file,
            },
            {
              headers: {
                "Content-Type": "multipart/form-data",
              },
            }
          )
          .then((data) => {
            this.$emit("update:modelValue", data);
          });
      },
  
      /**
       *
       * @param {*} size 文件大小
       * @param {*} type 文件类型
       * @returns true - 校验通过， false - 校验失败
       */
      fileCheck(size, type) {
        if (size > this.limit || !this.accept.includes(type)) {
          return false;
        } else {
          return true;
        }
      },
  
      handleDelete() {
        this.$emit("update:modelValue", "");
      },
    },
  };
  </script>
  
  <style lang="scss" scoped>
  .avatar-uploader {
    .avatar {
      position: relative;
      width: 120px;
      height: 120px;
      display: block;
  
      img {
        display: block;
        width: 100%;
        height: 100%;
      }
  
      .handle {
        position: absolute;
        top: 0;
        left: 0;
        display: none;
        align-items: center;
        justify-content: center;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        cursor: default;
      }
  
      .icon-delete {
        font-size: 28px;
        color: #fff;
        cursor: pointer;
      }
  
      &:hover {
        .handle {
          display: flex;
        }
      }
    }
  }
  
  .avatar-uploader ::v-deep(.el-upload) {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
  }
  
  .avatar-uploader ::v-deep(.el-upload:hover) {
    border-color: var(--el-color-primary);
  }
  
  .el-icon.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 120px;
    height: 120px;
    text-align: center;
  }
  </style>
  